/* 文件读取加载部分 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <malloc.h>
#include "comm.h"

/* map file, get size and memory pos */
void* open_file(char *filename, size_t *pFSize){
	int fd;
	void *start;
	struct stat sb;

	fd = open(filename, O_RDWR); 
	if (0 == fd){
		/* open file fail */
		PRINTF("open file failed\n");
		return NULL;
	}
	
	fstat(fd, &sb); /* read file size */
	start = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	if(start == MAP_FAILED) /* if map failed */{
		PRINTF("map failed!\n");
		return NULL;
	}
	
	PRINTF("mem pos:%p\t len:%ld\n", start, sb.st_size); 
	close(fd);

	*pFSize = sb.st_size;

	return start;
}


/* split buffer into segments */
t_segment *split_file(BYTE *start, size_t fsize, int segnum){
	int i = 0;
	size_t seglen = fsize / segnum;
	BYTE *end = start + fsize;
	BYTE *cursor = start;
	
	PRINTF("start = %p, end = %p, size=%ld, seglen = %ld\n", start, end, end-start, seglen);

	t_segment *pSegStart = (t_segment *)malloc(sizeof(t_segment)*segnum);
	t_segment *pSeg = pSegStart;
	
	for (i=0; i<segnum; i++){
		pSeg->segno = i;
		pSeg->start = cursor;
		
		cursor += seglen;
		/* move to \n  then end */
		while (*cursor != '\n' && cursor < end){
			cursor ++;
		}
		pSeg->end   = cursor;
		cursor ++;
		pSeg++;
	}
	pSeg--;
	pSeg->end = end-1;   /* last segment's end equal to file's end */

	/* for debug */
	pSeg = pSegStart;
	for (i=0; i<segnum; i++){
		PRINTF("i= %d, &pSeg=%p start=%p end=%p len=%ld\n", i, pSeg, pSeg->start, pSeg->end, pSeg->end - pSeg->start + 1);
		pSeg++;
	}
	//PRINTF("split_file return %p\n", pSegStart);
	return pSegStart;
	
}


